#!/bin/sh

######################################################################
# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. 
#
#  cawan     5/15/12   Create and support
#                          opatchauto apply, rollback
#  cawan     8/20/12   Fix Bug #14512559
#  cawan     9/18/12   Call OPatch class directly instead 
#                      of calling opatch command
######################################################################

BASE=`dirname $0`
PWD=`pwd`

argCount=$#
args=$@
CMDNAME=`basename $0`

# Look for OPATCH_DEBUG env variable
DEBUG=${OPATCH_DEBUG}

# Check for OPATCH_DEBUG
DEBUGVAL=false
if [ "$DEBUG" = "TRUE" ]; then
    DEBUGVAL=true;
fi
if [ "$DEBUG" = "true" ]; then
    DEBUGVAL=true;
fi

OH=${ORACLE_HOME}
JRE_MEMORY_OPTIONS=${OPATCH_JRE_MEMORY_OPTIONS}

oracleOcmService=""
if [ "$ORACLE_OCM_SERVICE" != "" ] ; then
  oracleOcmService="-Docm.endpoint=${ORACLE_OCM_SERVICE}"
fi

OPT_OH=
OPT_JDK=
OPT_JRE=
OPT_OUI=
OPT_INVPTR=

FINAL_OUI_LOCATION=

#opatchauto options specified flag
ohOpt=0
jdkOpt=0
jreOpt=0
ouiOpt=0
invOpt=0
databaseOpt=0
isHelp=0
isOper=0

if [ "$1" = "apply" -o "$1" = "rollback" ]; then
    isOper=1
fi

for arg in "$@"; do
    if [ $ohOpt = 1 ]; then
        OPT_OH=$arg
        ohOpt=0
    fi
    if [ $jdkOpt = 1 ]; then
        OPT_JDK=$arg
        jdkOpt=0
    fi
    if [ $jreOpt = 1 ]; then
        OPT_JRE=$arg
        jreOpt=0
    fi
    if [ $ouiOpt = 1 ]; then
        OPT_OUI=$arg
        FINAL_OUI_LOCATION=$arg
        
        if [ "$DEBUGVAL" = "true" ]; then
            echo opatchauto is provided with 'oui_loc' option as $OUI_LOCATION
        fi
        ouiOpt=0
    fi

    if [ $arg = "-oh" ]; then
        ohOpt=1
    fi
    if [ "$arg" = "-jre" ]; then
        jreOpt=1;
    fi
    if [ "$arg" = "-jdk" ]; then
        jdkOpt=1;
    fi
    if [ "$arg" = "-oui_loc" ]; then
        ouiOpt=1;
    fi
    if [ `echo $arg | tr [A-Z] [a-z]` = "-invptrloc" ]; then
        invOpt=1;
    fi

    if [ $arg = "-database" ]; then
        databaseOpt=1
    fi

    if [ $arg = "-h" -o $arg = "-help" ]; then
        isHelp=1
    fi
done

SCRIPTNAME=$0
case ${SCRIPTNAME} in
    /*) SCRIPTPATH=`dirname ${SCRIPTNAME}`;;
    *) SCRIPTPATH=`dirname ${PWD}/${SCRIPTNAME}`;;
esac
DETECT_OH=`cd ${SCRIPTPATH}/..; pwd`

OPT_OH=`echo $OPT_OH | sed -e 's|//*|/|g' | sed -e 's|/*$||g'`
OH=`echo $OH | sed -e 's|//*|/|g' | sed -e 's|/*$||g'`

if [ -n "$OPT_OH" ]; then
    if [ "$OPT_OH" != "$DETECT_OH" ]; then 
        if [ -d "$DETECT_OH/oui" ]; then
            echo "The working oracle home is inconsistent with the target one specified by option '-oh'. Please run the current command inside target home."
            echo "opatchauto returns with error code = 2"
            exit 2
        else
            echo opatchauto runs outside of oracle home or in a standalone home. Please run it inside a valid OUI based oracle home.
            echo "opatchauto returns with error code = 2"
            exit 2
        fi
    fi
    OH=$OPT_OH
else
    if [ -n "$OH" -a "$OH" != "$DETECT_OH" ]; then
        if [ -d "$DETECT_OH/oui" ]; then
            echo The working oracle home is inconsistent with the home set in environment variable ORACLE_HOME. Please reset or unset it and retry.
            echo "opatchauto returns with error code = 2"
            exit 2
        else
            echo opatchauto runs outside of oracle home or in a standalone home. Please run it inside a valid OUI based oracle home.
            echo "opatchauto returns with error code = 2"
            exit 2
        fi
    fi
    OH=$DETECT_OH
fi

if [ ! -d "$OH" ]; then
    echo The Oracle Home $OH does not exist. Please give a proper home and retry.
    echo opatchauto returns with error code = 2
    exit 2
fi

if [ ! -d "$OH/oui" ]; then
    echo The Oracle Home $OH is not an OUI based home. Please give a proper home and retry.
    echo opatchauto returns with error code = 2
    exit 2
fi

PLATFORM=`uname`
OLRLOC=

case $PLATFORM in
    Linux)
       OLRLOC="/etc/oracle/olr.loc"
       LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH
       # Linux ( ppc64 || s390x ) => LD_LIBRARY_PATH lib32
       ARCH=`uname -m`;
       if [ "$ARCH" = "ppc64" -o "$ARCH" = "s390x" ]
       then
           LD_LIBRARY_PATH=$OH/lib32:$OH/srvm/lib32:$LD_LIBRARY_PATH
       fi
       export LD_LIBRARY_PATH
       ;;
    HP-UX)
       OLRLOC="/var/opt/oracle/olr.loc"
       LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib
       export LD_LIBRARY_PATH
       SHLIB_PATH=
       export SHLIB_PATH
       ;;
    AIX)
       OLRLOC="/etc/oracle/olr.loc"
       LIBPATH=$OH/lib:$OH/srvm/lib:$LIBPATH
       export LIBPATH
       OBJECT_MODE="32_64"
       export OBJECT_MODE
       ;;
    SunOS)
       OLRLOC="/var/opt/oracle/olr.loc"
       LD_LIBRARY_PATH_64=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH_64
       export LD_LIBRARY_PATH_64
       LD_LIBRARY_PATH=$OH/lib:$OH/srvm/lib:$LD_LIBRARY_PATH
       export LD_LIBRARY_PATH
       ;;
    *)
       echo "ERROR: $PLATFORM is not supported. opatchauto cannot proceed!"
       echo "opatchauto returns with error code = 2"
       exit 2
esac

CRSHOME=
if [ -f $OLRLOC ]; then
    CRSHOME=`cat $OLRLOC | grep "^crs_home=" | sed 's/crs_home=//'`
fi

if [ $isHelp != 1 -a $isOper = 1 ]; then
    if [ $databaseOpt = 1 ]; then
        CRSCTL=`ls -a "$OH/bin" | grep crsctl`
        if [ -n "$CRSCTL" ]; then
            echo "opatchauto cannot proceed from Grid Home when patching database home. Please run it inside database home"
            echo opatchauto returns with error code = 2
            exit 2
        fi
    elif [ -z "$OPT_OH" ]; then
        CRSCTL=`ls -a "$OH/bin" | grep crsctl`
        if [ -z "$CRSCTL" ]; then
            echo "opatchauto proceeds only from Grid Home with current arguments. Please run it inside Grid Home"
            echo "opatchauto returns with error code = 2"
            exit 2
        elif [ -n "$CRSHOME" -a "$OH" != "$CRSHOME" ]; then
            echo "The running Oracle Home is not a valid Grid Home. Please check and retry"
            echo "opatchauto returns with error code = 2"
            exit 2
        fi
    fi
fi

if [ "$OPT_OUI" = "" -o ! -d "${OPT_OUI}" ]; then
   OUI_LOCATION=$OH/oui
   FINAL_OUI_LOCATION=$OH/oui
   if [ ! "$OUI_LOCATION" = "" -a -d "${OUI_LOCATION}" ]; then
       OUI_LOCATION=""
   fi
fi

invptr=
if [ -r "${OH}/oraInst.loc" ]; then
    if [ $argCount -ge 1 -a $invOpt -eq 0 ]; then
        invptr=" -invPtrLoc ${OH}/oraInst.loc"
    fi
fi

JAVA= # Default location

# Use JRE if supplied
if [ "$JAVA" = "" ] && [ "$OPT_JRE" != "" ]; then # from -jre
  JAVA=$OPT_JRE/bin/java
  JAVA_HOME=$OPT_JRE
fi


# Use JDK if supplied
if [ "$JAVA" = "" ] && [ "$OPT_JDK" != "" ]; then # now from -jdk
  JAVA=$OPT_JDK/bin/java
  JAVA_HOME=$OPT_JDK
fi


# use OH/jre/*, it should be 1.5 or above
if [ "$JAVA" = "" ] ; then
  JRE_HIGH=
  if [ -d $OH/jre ]; then
    for i in `ls -1 $OH/jre | sort` ;
    do
      JRE_HIGH=$i ;
    done
    if [ "$JRE_HIGH" != "" ]; then
      JRE_HIGH_FINAL=`echo $JRE_HIGH | awk '
                            BEGIN {FS="."}
                            {
                                if (($1 >= 1) && ($2 >= 5))
                                    print $0
                            }'`
      if [ "$JRE_HIGH_FINAL" != "" ] && [ -x $OH/jre/$JRE_HIGH_FINAL/bin/java ]; then
          JAVA=$OH/jre/$JRE_HIGH_FINAL/bin/java
          JAVA_HOME=$OH/jre/$JRE_HIGH_FINAL
      fi
    fi
  fi
fi

# Now Check for jdk location inside OH
if [ "$JAVA" = "" ] && [ -d $OH/jdk ]; then  # Now look for jdk in OH
  JAVA=$OH/jdk/bin/java
  JAVA_HOME=$OH/jdk
fi

if [ "$JAVA_HOME" = "" ]; then
    if [ -d $OH/../jdk6 ]; then
        if [ "$DEBUGVAL" = "true" ]; then
            echo "Looking for java in $OH/../jdk6"
        fi
        JAVA_HOME=$OH/../jdk6
        JAVA=$JAVA_HOME/bin/java
        if [ ! -x $JAVA ]; then
            JAVA_HOME=""
            JAVA=""
        else
            if [ "$DEBUGVAL" = "true" ]; then
                echo "Setting java to $JAVA"
            fi
        fi
   fi
fi

# Last option is to look inside oraparam.ini for JRE_LOCATION
if [ "$JAVA" = "" ] && [ -r $FINAL_OUI_LOCATION/oraparam.ini ]; then
  if [ "$DEBUGVAL" = "true" ]; then
      echo "Looking for java in $FINAL_OUI_LOCATION/oraparam.ini"
  fi
  JRE_LOCATION=`grep "JRE_LOCATION=" $FINAL_OUI_LOCATION/oraparam.ini | sed 's/JRE_LOCATION=//'`
  ABS_PATH=`echo $JRE_LOCATION | grep "^\/"`
  if [ "$ABS_PATH" = "" ] && [ -d $FINAL_OUI_LOCATION/bin/$JRE_LOCATION ]; then # not absolute path
    JAVA=$FINAL_OUI_LOCATION/bin/$JRE_LOCATION/bin/java
    JAVA_HOME=$FINAL_OUI_LOCATION/bin/$JRE_LOCATION
  else
      if [ -d $JRE_LOCATION ]; then
          JAVA=$JRE_LOCATION/bin/java
          JAVA_HOME=$JRE_LOCATION
      fi
  fi
fi

# Now check if Java executable exists and has execute permission, exit otherwise
# Because from this point on we cannot proceed without Java 
if [ "$JAVA" = "" -o ! -x "$JAVA" ]; then
   if [ "$JAVA" = "" ]; then
      echo Java could not be located. opatchauto cannot proceed!
      echo "opatchauto returns with error code = 2"
      exit 2
   fi
   if [ ! -x "$JAVA" ]; then
      echo $JAVA is not a valid executable for this platform. opatchauto cannot proceed!
      echo "opatchauto returns with error code = 2"
      exit 2
   fi
fi

if  [ "$DEBUGVAL" = "true" ]; then
    _osArch=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp os.arch`
    _javaVMSpecVersion=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.specification.version`
    _javaVMSpecVendor=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.specification.vendor`
    _javaVMSpecName=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.specification.name`
    _javaVMVendor=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.vm.vendor`
    _javaJRESpecVersion=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.specification.version`
    _javaJRESpecVendor=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.specification.vendor`
    _javaJRESpecName=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.specification.name`
    _javaSupportedClassVersion=`$JAVA -cp $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp java.class.version`
    if [ -x "$JAVA_HOME/bin/javap" ]; then 
      _javaCompiledClassMajorVersion=`$JAVA_HOME/bin/javap -verbose -classpath $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp |grep major|sed 's/^ *\(.*\) *$/\1/'`
      _javaCompiledClassMinorVersion=`$JAVA_HOME/bin/javap -verbose -classpath $BASE/jlib/opatch.jar oracle.opatch.JavaSystemProp|grep minor|sed 's/^ *\(.*\) *$/\1/'`
    fi
    _unameall=`uname -a`
    echo "Machine Info: $_unameall"
    echo "_osArch is $_osArch"
    echo "_javaVMSpecVersion is $_javaVMSpecVersion"
    echo "_javaVMSpecVendor is $_javaVMSpecVendor"
    echo "_javaVMSpecName is $_javaVMSpecName"
    echo "_javaVMVendor is $_javaVMVendor"
    echo "_javaJRESpecVersion is $_javaJRESpecVersion"
    echo "_javaJRESpecVendor is $_javaJRESpecVendor"
    echo "_javaJRESpecName is $_javaJRESpecName"
    echo "_javaSupportedClassVersion is $_javaSupportedClassVersion"
    echo "opatchauto compiled with $_javaCompiledClassMajorVersion, $_javaCompiledClassMinorVersion"
fi

# set _bootClassPath for IBM platforms (bug 7038091 and 7114214)
_osArch=""
if [ -r $BASE/ocm/lib/emocmcommon.jar ] && [ -r $BASE/ocm/ocm.zip ]; then
   _osArch=`$JAVA -cp $BASE/ocm/lib/emocmcommon.jar OsInfo`
fi
_bootClassPath=""

if  [ "$DEBUGVAL" = "true" ]; then
    echo "_osArch (from OCM API) is $_osArch"
fi
if [ "${_osArch}" = "ppc" -o "${_osArch}" = "ppc64" -o "${_osArch}" = "s390"  -o "${_osArch}" = "s390x" ]; then
      _bootClassPath="-Xbootclasspath/a:${BASE}/ocm/lib/emocmclnt.jar:${BASE}/ocm/lib/emocmcommon.jar:${BASE}/ocm/lib/emocmclnt-14.jar:${BASE}/ocm/lib/osdt_core3.jar:${BASE}/ocm/lib/osdt_jce.jar:${BASE}/ocm/lib/http_client.jar:${BASE}/ocm/lib/regexp.jar:${BASE}/ocm/lib/jcert.jar:${BASE}/ocm/lib/jnet.jar:${BASE}/ocm/lib/jsse.jar:${BASE}/ocm/lib/log4j-core.jar:${BASE}/ocm/lib/xmlparserv2.jar"
      if  [ "$DEBUGVAL" = "true" ]; then
        echo "IBM platforms: set _bootClassPath to $_bootClassPath"
      fi
fi


# JRE_MEMORY_OPTIONS 

if [ -z "${JRE_MEMORY_OPTIONS}" ]; then
   JRE_MEMORY_OPTIONS=""
   if [ -r $FINAL_OUI_LOCATION/oraparam.ini ]; then
      JRE_MEMORY_OPTIONS=`grep -v "^#" $FINAL_OUI_LOCATION/oraparam.ini | grep "^JRE_MEMORY_OPTIONS=" | sed 's/JRE_MEMORY_OPTIONS=//' | head -1`
        JROCKIT=`echo $JDK | grep "jrockit"`;
	if [ ! -z "${JROCKIT}" ]; then
            JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/XX:MaxPermSize=/ms/'`;
	fi
   fi
else
   D64_OPTIONS=`echo $JRE_MEMORY_OPTIONS | grep "\-d64"`
   if [ -z "${D64_OPTIONS}" ]; then
      if [ -r $FINAL_OUI_LOCATION/oraparam.ini ]; then
         D64_OPTIONS=`grep -v "^#" $FINAL_OUI_LOCATION/oraparam.ini | grep "^JRE_MEMORY_OPTIONS=" | sed 's/JRE_MEMORY_OPTIONS=//' | head -1 | grep " \-d64"`
      fi
      if [ ! -z "${D64_OPTIONS}" ]; then
         D64=" -d64"
         JRE_MEMORY_OPTIONS=$JRE_MEMORY_OPTIONS$D64   
      fi
   fi 
fi

# Remove double quotes globally - whatever u get
JRE_MEMORY_OPTIONS=`echo $JRE_MEMORY_OPTIONS | sed 's/\"//g'`


# Change the permission of OH/.patch_storage directory and set umask.
# umask 0007 
# Do not set umask.
patchStorage="$OH/.patch_storage"
chmodResult=0
if [ -d $patchStorage ]; then
   chmod o-rwx $patchStorage  > /dev/null
   chmodResult=$?
fi

if [ $chmodResult != 0 ]; then
   echo "The chmod command failed for ".$patchStorage.". It is possible that you have no permission to access it. opatchauto cannot proceed!"
   echo "opatchauto returns with error code = 2"
   exit 2
fi

if [ "$OUI_LOCATION" != "" ] ; then
CP=$OUI_LOCATION/jlib
else
CP=$OH/oui/jlib
fi

if [ "$DEBUGVAL" = "true" ]; then
    echo "$JAVA $JAVA_VM_OPTION $JRE_MEMORY_OPTIONS -cp $BASE/ocm/lib/emocmclnt.jar:$CP/OraInstaller.jar:$CP/OraPrereq.jar:$CP/share.jar:$CP/orai18n-mapping.jar:$CP/xmlparserv2.jar:$CP/emCfg.jar:$CP/ojmisc.jar:$BASE/jlib/opatch.jar:$BASE/jlib/opatchsdk.jar:$BASE/oplan/jlib/automation.jar:$BASE/oplan/jlib/apache-commons/commons-cli-1.0.jar:$BASE/jlib/oracle.opatch.classpath.jar:$BASE/oplan/jlib/jaxb/activation.jar:$BASE/oplan/jlib/jaxb/jaxb-api.jar:$BASE/oplan/jlib/jaxb/jaxb-impl.jar:$BASE/oplan/jlib/jaxb/jsr173_1.0_api.jar:$BASE/oplan/jlib/OsysModel.jar:$BASE/oplan/jlib/osysmodel-utils.jar:$BASE/oplan/jlib/CRSProductDriver.jar:$BASE/oplan/jlib/oracle.oplan.classpath.jar -DOPatch.ORACLE_HOME=$OH -DOPatch.DEBUG=$DEBUGVAL -DOPatch.RUNNING_DIR=$BASE -DOPatch.OUI_LOCATION=$OUI_LOCATION -DOPatch.OPATCH_CLASSPATH=$CLASSPATH -DOPatch.CALLER=$CMDNAME ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $args $invptr"
fi


    $JAVA $JAVA_VM_OPTION $JRE_MEMORY_OPTIONS -cp "$BASE/ocm/lib/emocmclnt.jar:$CP/OraInstaller.jar:$CP/OraPrereq.jar:$CP/share.jar:$CP/orai18n-mapping.jar:$CP/xmlparserv2.jar:$CP/emCfg.jar:$CP/ojmisc.jar:$BASE/jlib/opatch.jar:$BASE/jlib/opatchsdk.jar:$BASE/oplan/jlib/automation.jar:$BASE/oplan/jlib/apache-commons/commons-cli-1.0.jar:$BASE/jlib/oracle.opatch.classpath.jar:$BASE/oplan/jlib/jaxb/activation.jar:$BASE/oplan/jlib/jaxb/jaxb-api.jar:$BASE/oplan/jlib/jaxb/jaxb-impl.jar:$BASE/oplan/jlib/jaxb/jsr173_1.0_api.jar:$BASE/oplan/jlib/OsysModel.jar:$BASE/oplan/jlib/osysmodel-utils.jar:$BASE/oplan/jlib/CRSProductDriver.jar:$BASE/oplan/jlib/oracle.oplan.classpath.jar" -DOPatch.ORACLE_HOME="$OH" -DOPatch.DEBUG="$DEBUGVAL" -DOPatch.RUNNING_DIR="$BASE" -DOPatch.OUI_LOCATION="$OUI_LOCATION" -DOPatch.OPATCH_CLASSPATH="$CLASSPATH" -DOPatch.CALLER="$CMDNAME" ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $args $invptr

RESULT=$?

if [ $argCount -ge 1 ] && [ "$1" = "lspatches" ]; then
   exit ${RESULT}
fi

if [ $RESULT -ge  5 ] && [ $RESULT -le 7 ]; then
  echo
  echo "opatchauto stopped on request."
  RESULT=0
elif [ $RESULT -eq 8 ] ;then
  echo
  echo "opatchauto completed with warnings.";
  RESULT=0
elif [ $RESULT != 0 ]; then
  echo
  echo "opatchauto failed with error code $RESULT.";
else
  echo 
  echo "opatchauto succeeded."
fi

exit ${RESULT}
